package com.dxj.service.impl;
import com.baomidou.mybatisplus.core.batch.MybatisBatch;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dxj.domain.Permission;
import com.dxj.domain.Role;
import com.dxj.domain.RolePermission;
import com.dxj.mapper.PermissionMapper;
import com.dxj.mapper.RoleMapper;
import com.dxj.mapper.RolePermissionMapper;
import com.dxj.request.RolePageDTO;
import com.dxj.request.RolePermissionDTO;
import com.dxj.response.PageResultVo;
import com.dxj.response.R;
import com.dxj.response.RoleInfoVo;
import com.dxj.service.IRoleService;
import io.github.linpeilie.Converter;
import io.github.linpeilie.utils.CollectionUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author dxj
 * @Description 角色服务实现类
 * @date 2024/7/30 18:39
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
    @Resource
    private Converter converterMapper;
    @Resource
    private SqlSessionFactory sqlSessionFactory;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Resource
    private PermissionMapper permissionMapper;

    /**
     * 插入角色并分配权限
     * @param rolePermissionDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R insertRole(RolePermissionDTO rolePermissionDTO) {
        Role role=converterMapper.convert(rolePermissionDTO,Role.class);
        baseMapper.insert(role);
        //维护角色权限
        List<Long> permissionIds = rolePermissionDTO.getPermissionId();
        updateRolePermission(permissionIds,role.getId());
        return R.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R roleDelete(Long id) {
        //TODO 如果是管理员角色，不允许删除
        baseMapper.deleteById(id);
        //删除该角色关联的权限信息
        rolePermissionMapper.delete(new LambdaQueryWrapper<RolePermission>().eq(RolePermission::getRoleId,id));
        return R.success();
    }

    /**
     * 角色信息列表分页
     * @param rolePageDTO
     * @return
     */
    @Override
    public R<PageResultVo<RoleInfoVo>> roleList(RolePageDTO rolePageDTO) {
        IPage<Role> page = new Page<>(rolePageDTO.getPageNum(), rolePageDTO.getPageSize());
        //查询条件
        LambdaQueryWrapper<Role> lambdaQuery = new LambdaQueryWrapper<>();
        lambdaQuery.select(Role::getId,Role::getRoleName,Role::getDescription);
        lambdaQuery.likeLeft(StringUtils.hasText(rolePageDTO.getRoleName()), Role::getRoleName, rolePageDTO.getRoleName());
        lambdaQuery.likeLeft(StringUtils.hasText(rolePageDTO.getDescription()), Role::getDescription, rolePageDTO.getDescription());
        // 调用 selectPage分页方法
        IPage<Role> RolePage = baseMapper.selectPage(page, lambdaQuery);
        long total = RolePage.getTotal();
        List<Role> RoleList = RolePage.getRecords();
        //构建真正返回的数据
        List<RoleInfoVo> roleInfoVoList = RoleList.stream().map((item) -> {
            //TODO 避免在循环里面查数据库
            RoleInfoVo roleInfoVo=converterMapper.convert(item,RoleInfoVo.class);
            //查询该角色绑定的权限信息
           List<RolePermission> rolePermission=rolePermissionMapper.selectList(new LambdaQueryWrapper<RolePermission>()
                    .eq(RolePermission::getRoleId,roleInfoVo.getId())
                    .select(RolePermission::getPermissionId));
           List<Permission> permission=permissionMapper.selectList(new LambdaQueryWrapper<Permission>()
                    .in(Permission::getId,rolePermission.stream().map(RolePermission::getPermissionId).collect(Collectors.toList()))
                    .select(Permission::getDescription));
            //设置权限信息
            roleInfoVo.setPermissions(permission.stream().map(Permission::getDescription).collect(Collectors.toSet()));
            return roleInfoVo;
        }).collect(Collectors.toList());
        PageResultVo<RoleInfoVo> resultVo = new PageResultVo();
        resultVo.setTotal(total);
        resultVo.setRecords(roleInfoVoList);
        return R.success("操作成功", resultVo);
    }

    /**
     * 维护该角色的权限
     * @param permissionIds
     * @param roleId
     */
    public void updateRolePermission(List<Long> permissionIds,Long roleId) {
        if (CollectionUtils.isNotEmpty(permissionIds)) {
            List<RolePermission> rolesPermissionList = permissionIds.stream()
                    .map(permissionId -> {
                        RolePermission rolePermission = new RolePermission();
                        rolePermission.setRoleId(roleId);
                        rolePermission.setPermissionId(permissionId);
                        return rolePermission;
                    }).collect(Collectors.toList());
            //批量插入userRole
            if (rolesPermissionList.size() > 0) {
                MybatisBatch<RolePermission> mybatisBatch = new MybatisBatch<>(sqlSessionFactory, rolesPermissionList);
                MybatisBatch.Method<RolePermission> method = new MybatisBatch.Method<>(RolePermissionMapper.class);
                mybatisBatch.execute(method.insert());
            }
        }
    }
}
